//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <RenderLibServer.h>

////////////////////////////////////////////////////////////////////////////
//                         ScanLine Render Utility                        //
////////////////////////////////////////////////////////////////////////////
Void ScanLineRGB24ToRGB24(
                Address destination, Address source, Int32 stride)
{
    Pixel *dst = (Pixel *)destination;
    Pixel *src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderRGB24ToRGB24((Address)dst, (Address)src);

        dst++;
        src++;
        stride--;
    }
}


//Void ScanLineRGB24ToRGB24WithOpacity(
//                Pixel* dst, Pixel* src, Int32 stride, UInt8 srcOpacity)
//{
//    assert(dst && src && stride > 0);
//    assert(0xFF != srcOpacity && 0x00 != srcOpacity);
//
//     do {
//        PixelRenderRGB24ToRGB24WithOpacity(dst, src, srcOpacity);
//
//        src++;
//        dst++;
//        stride--;
//
//    } while (stride > 0);
//}

Void ScanLineARGB32ToRGB24(
                Address destination, Address source, Int32 stride)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToRGB24((Address)dst, (Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineARGB32ToRGB24WithOpacity(
                Address destination, Address source, Int32 stride, UInt8 srcOpacity)
{
    assert(0xFF != srcOpacity && 0x00 != srcOpacity);

    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToRGB24WithOpacity((Address)dst, (Address)src, srcOpacity);

        src++;
        dst++;
        stride--;
    }
}

//Void ScanLineRGB24ToARGB32(
//                Pixel* dst, Pixel* src, Int32 stride)
//{
//    assert(dst && src && stride > 0);
//
//    do {
//        PixelRenderRGB24ToARGB32(dst, src);
//
//        src++;
//        dst++;
//        stride--;
//
//    } while (stride > 0);
//}

//Void ScanLineRGB24ToARGB32WithOpacity(
//                Pixel* dst, Pixel* src, Int32 stride, UInt8 srcOpacity)
//{
//    assert(dst && src && stride > 0);
//
//    assert(0xFF != srcOpacity && 0x00 != srcOpacity);
//
//    do {
//        PixelRenderRGB24ToARGB32WithOpacity(dst, src, srcOpacity);
//
//        src++;
//        dst++;
//        stride--;
//
//    } while (stride > 0);
//}

//Void ScanLineARGB32ToARGB32(
//                Pixel* dst, Pixel* src, Int32 stride)
//{
//    assert(dst && src && stride > 0);
//
//    do {
//        PixelRenderARGB32ToARGB32(dst, src);
//
//        src++;
//        dst++;
//        stride--;
//
//    } while (stride > 0);
//}
//
//Void ScanLineARGB32ToARGB32WithOpacity(
//                Pixel* dst, Pixel* src, Int32 stride, UInt8 srcOpacity)
//{
//    assert(dst && src && stride > 0);
//    assert(0xFF != srcOpacity && 0x00 != srcOpacity);
//
//    do {
//        PixelRenderARGB32ToARGB32WithOpacity(dst, src, srcOpacity);
//
//        src++;
//        dst++;
//        stride--;
//
//    } while (stride > 0);
//}

Void ScanLineA8ToRGB24(
                Address destination, Address src, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToRGB24((Address)dst, src, srcColor);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineA8ToRGB24WithColorAlpha(
                Address destination, Address src, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToRGB24WithColorAlpha((Address)dst, src, srcColor);

        src++;
        dst++;
        stride--;
    }
}

//Void ScanLineA8ToARGB32(
//                Pixel* dst, UInt8* src, Int32 stride, Pixel srcColor)
//{
//    assert(0xFF == srcColor.a);
//    assert(dst && src && stride > 0);
//
//    do {
//        PixelRenderA8ToARGB32(dst, src, srcColor);
//
//        src++;
//        dst++;
//        stride--;
//
//    } while (stride > 0);
//}
//
//Void ScanLineA8ToARGB32WithColorAlpha(
//                Pixel* dst, UInt8* src, Int32 stride, Pixel srcColor)
//{
//    assert(dst && src && stride > 0);
//
//    do {
//        PixelRenderA8ToARGB32WithColorAlpha(dst, src, srcColor);
//
//        src++;
//        dst++;
//        stride--;
//
//    } while (stride > 0);
//}


Void ScanLineSetColorARGB32(
                Address destination, Int32 stride, Pixel srcColor)
{
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelSetColorARGB32((Address)dst, srcColor);

        dst++;
        stride--;
    }
}

//Void ScanLineSetColorARGB32WithColorAlpha(
//                Pixel* dst, Int32 stride, Pixel srcColor)
//{
//    while (stride > 0) {
//        PixelSetColorARGB32WithColorAlpha(dst, srcColor);
//
//        dst++;
//        stride--;
//    }
//}


Void ZoomScanLineRGB24ToRGB24(
                Address destination, Int32 stride,
                Address source, UInt32 xrIntFloat_16, UInt32 srcx_16)
{

    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderRGB24ToRGB24((Address)dst, (Address)(src + (srcx_16>>16)));

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineRGB24ToRGB24WithOpacity(
                Address destination, Int32 stride,
                Address source, UInt32 xrIntFloat_16, UInt8 opacity, UInt32 srcx_16)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    do {
        PixelRenderRGB24ToRGB24WithOpacity(
                (Address)dst, (Address)(src + (srcx_16>>16)), opacity);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }while(stride > 0);
}


Void ZoomScanLineRGB24ToARGB32(
                Address destination, Int32 stride,
                Address source, UInt32 xrIntFloat_16, UInt32 srcx_16)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderRGB24ToARGB32((Address)dst, (Address)(src + (srcx_16>>16)));

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

//Void ZoomScanLineRGB24ToARGB32WithOpacity(
//                Pixel* dst, Int32 stride,
//                Pixel* src, UInt32 xrIntFloat_16, UInt8 opacity)
//{
//
//    for (Int32 x = 0; x < stride; ++x) {
//        PixelRenderRGB24ToARGB32WithOpacity(
//                dst++, src + (srcx_16>>16), opacity);
//
//        srcx_16 += xrIntFloat_16;
//    }
//}

Void ZoomScanLineARGB32ToRGB24(
                Address destination, Int32 stride,
                Address source, UInt32 xrIntFloat_16, UInt32 srcx_16)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToRGB24((Address)dst, (Address)(src + (srcx_16>>16)));

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineARGB32ToRGB24WithOpacity(
                Address destination, Int32 stride,
                Address source, UInt32 xrIntFloat_16, UInt8 opacity, UInt32 srcx_16)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToRGB24WithOpacity(
                (Address)dst, (Address)(src + (srcx_16>>16)), opacity);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineARGB32ToARGB32(
                Address destination, Int32 stride,
                Address source, UInt32 xrIntFloat_16, UInt32 srcx_16)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToARGB32((Address)dst, (Address)(src + (srcx_16>>16)));

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineARGB32ToARGB32WithOpacity(
                Address destination, Int32 stride,
                Address source, UInt32 xrIntFloat_16, UInt8 opacity, UInt32 srcx_16)
{
    Pixel* dst = (Pixel *)destination;
    Pixel* src = (Pixel *)source;

    while (stride > 0) {
        PixelRenderARGB32ToARGB32WithOpacity(
                (Address)dst, (Address)(src + (srcx_16>>16)), opacity);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineA8ToRGB24(
                Address destination, Int32 stride, Address src,
                UInt32 xrIntFloat_16, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToRGB24((Address)dst, src + (srcx_16>>16), srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineA8ToRGB24WithColorAlpha(
                Address destination, Int32 stride, Address src,
                UInt32 xrIntFloat_16, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToRGB24WithColorAlpha(
                (Address)dst, src + (srcx_16>>16), srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineA8ToARGB32(
                Address destination, Int32 stride, Address src,
                UInt32 xrIntFloat_16, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToARGB32((Address)dst, src + (srcx_16>>16), srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ZoomScanLineA8ToARGB32WithColorAlpha(
                Address destination, Int32 stride, Address src,
                UInt32 xrIntFloat_16, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;

    while (stride > 0) {
        PixelRenderA8ToARGB32WithColorAlpha(
                (Address)dst, src + (srcx_16>>16), srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

//Void BilinearScanLineRGB24ToRGB24(
//                Pixel* dst, Pixel* src, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride)
//{
//    UInt32 srcx_16 = 0;
//
//    for (Int32 x = 0; x < stride; ++x) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        Pixel result = BilinearQuadARGB32(
//                        (Pixel*)(src + (srcx_16>>16)),
//                        (Pixel*)(color0Addr + srcPitch),
//                        (srcx_16 & 0xFFFF)>>8, v_8);
//
//        PixelRenderRGB24ToRGB24(dst++, &result);
//
//        srcx_16 += xrIntFloat_16;
//    }
//}

//Void BilinearScanLineRGB24ToRGB24WithOpacity(
//                Pixel* dst, Pixel* src, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride,
//                UInt8 opacity)
//{
//    UInt32 srcx_16 = 0;
//
//    for (Int32 x = 0; x < stride; ++x) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        PixelRenderRGB24ToRGB24WithOpacity(dst++, &BilinearQuadRGB24(
//                (Pixel*)color0Addr, (Pixel*)(color0Addr + srcPitch),
//                (srcx_16 & 0xFFFF)>>8, v_8), opacity);
//
//        srcx_16 += xrIntFloat_16;
//    }
//}

//Void BilinearScanLineRGB24ToARGB32(
//                Pixel* dst, Pixel* src, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride)
//{
//    UInt32 srcx_16 = 0;
//
//    for (Int32 x = 0; x < stride; ++x) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        PixelRenderRGB24ToARGB32(dst++, &BilinearQuadRGB24(
//                (Pixel*)color0Addr, (Pixel*)(color0Addr + srcPitch),
//                (srcx_16 & 0xFFFF)>>8, v_8));
//
//        srcx_16 += xrIntFloat_16;
//    }
//}

//Void BilinearScanLineRGB24ToARGB32WithOpacity(
//                Pixel* dst, Pixel* src, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride, UInt8 opacity)
//{
//    UInt32 srcx_16 = 0;
//
//    for (Int32 x = 0; x < stride; ++x) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        PixelRenderRGB24ToARGB32WithOpacity(dst++, &BilinearQuadRGB24(
//                (Pixel*)color0Addr, (Pixel*)(color0Addr + srcPitch),
//                (srcx_16 & 0xFFFF)>>8, v_8), opacity);
//
//        srcx_16 += xrIntFloat_16;
//    }
//}

//
//Void BilinearScanLineARGB32ToRGB24(
//                Address destination, Address source, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride)
//{
//    UInt32 srcx_16 = 0;
//    Pixel* dst = (Pixel *)destination;
//    Pixel* src = (Pixel *)source;
//
//    while (stride > 0) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        Pixel srcARGB32 = BilinearQuadARGB32(
//                color0Addr, (color0Addr + srcPitch),
//                (srcx_16 & 0xFFFF)>>8, v_8);
//
//        PixelRenderARGB32ToRGB24((Address)dst, (Address)&srcARGB32);
//
//        dst++;
//        stride--;
//        srcx_16 += xrIntFloat_16;
//    }
//}
//
//Void BilinearScanLineARGB32ToRGB24WithOpacity(
//                Address destination, Address source, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride, UInt8 opacity)
//{
//    UInt32 srcx_16 = 0;
//    Pixel* dst = (Pixel *)destination;
//    Pixel* src = (Pixel *)source;
//
//    while (stride > 0) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        Pixel srcARGB32 = BilinearQuadARGB32(
//                color0Addr, (color0Addr + srcPitch),
//                (srcx_16 & 0xFFFF)>>8, v_8);
//
//        PixelRenderARGB32ToRGB24WithOpacity((Address)dst, (Address)&srcARGB32, opacity);
//
//        dst++;
//        stride--;
//        srcx_16 += xrIntFloat_16;
//    }
//}
//
//Void BilinearScanLineARGB32ToARGB32(
//               Pixel* dst, Pixel* src, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride)
//{
//    UInt32 srcx_16 = 0;
//
//    for (Int32 x = 0; x < stride; ++x) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        PixelRenderARGB32ToARGB32(dst++, &BilinearQuadRGB24(
//                (Pixel*)color0Addr, (Pixel*)(color0Addr + srcPitch),
//                (srcx_16 & 0xFFFF)>>8, v_8));
//
//        srcx_16 += xrIntFloat_16;
//    }
//}

//Void BilinearScanLineARGB32ToARGB32WithOpacity(
//                Pixel* dst, Pixel* src, Int32 srcPitch, UInt32 v_8,
//                UInt32 xrIntFloat_16, Int32 stride, UInt8 opacity)
//{
//    UInt32 srcx_16 = 0;
//
//    for (Int32 x = 0; x < stride; ++x) {
//        Address color0Addr = (Address)(src + (srcx_16>>16));
//
//        Pixel srcPixel = BilinearQuadRGB24(
//                (Pixel*)color0Addr, (Pixel*)(color0Addr + srcPitch),
//                (srcx_16 & 0xFFFF)>>8, v_8);
//
//        PixelRenderARGB32ToARGB32WithOpacity(dst++, &srcPixel, opacity);
//
//        srcx_16 += xrIntFloat_16;
//    }
//}

Void BilinearScanLineA8ToRGB24(
                Address destination, Int32 stride, Address source, Int32 srcPitch,
                UInt32 xrIntFloat_16, UInt32 v_8, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;
    UInt8* src = (UInt8 *)source;

    while (stride > 0) {
        Address color0Addr = (Address)(src + (srcx_16>>16));

        UInt8 srcA8 = BilinearQuadA8(
                color0Addr, (color0Addr + srcPitch),
                (srcx_16 & 0xFFFF)>>8, v_8);

        PixelRenderA8ToRGB24((Address)dst, (Address)&srcA8, srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void BilinearScanLineA8ToRGB24WithColorAlpha(
                Address destination, Int32 stride, Address source, Int32 srcPitch,
                UInt32 xrIntFloat_16, UInt32 v_8, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;
    UInt8* src = (UInt8 *)source;

    while (stride > 0) {
        Address color0Addr = (Address)(src + (srcx_16>>16));

        UInt8 srcA8 = BilinearQuadA8(
                color0Addr, (color0Addr + srcPitch),
                (srcx_16 & 0xFFFF)>>8, v_8);

        PixelRenderA8ToRGB24WithColorAlpha((Address)dst, (Address)&srcA8, srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void BilinearScanLineA8ToARGB32(
                Address destination, Int32 stride, Address source, Int32 srcPitch,
                UInt32 xrIntFloat_16, UInt32 v_8, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;
    UInt8* src = (UInt8 *)source;

    while (stride > 0) {
        Address color0Addr = (Address)(src + (srcx_16>>16));

        UInt8 srcA8 = BilinearQuadA8(
                color0Addr, (color0Addr + srcPitch),
                (srcx_16 & 0xFFFF)>>8, v_8);

        PixelRenderA8ToARGB32((Address)dst, (Address)&srcA8, srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void BilinearScanLineA8ToARGB32WithColorAlpha(
                Address destination, Int32 stride, Address source, Int32 srcPitch,
                UInt32 xrIntFloat_16, UInt32 v_8, Pixel srcColor)
{
    UInt32 srcx_16 = 0;
    Pixel* dst = (Pixel *)destination;
    UInt8* src = (UInt8 *)source;

    while (stride > 0) {
        Address color0Addr = (Address)(src + (srcx_16>>16));
        UInt8 srcA8 = BilinearQuadA8(
                color0Addr, (color0Addr + srcPitch),
                (srcx_16 & 0xFFFF)>>8, v_8);

        PixelRenderA8ToARGB32WithColorAlpha((Address)dst, (Address)&srcA8, srcColor);

        dst++;
        stride--;
        srcx_16 += xrIntFloat_16;
    }
}

Void ScanLineRECT888To565(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16 *)destination;

    while (stride > 0) {
        *dst = Pixel888To565((Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineRECT888To565FLIP(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16 *)destination;

    while (stride > 0) {
        *--dst = Pixel888To565((Address)src);

        src++;
        stride--;
    }
}

Void ScanLineRECT888To565RCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16 *)destination;

    while (stride > 0) {
        *dst = Pixel888To565((Address)src);

        src++;
        dst = (UInt16*)((UInt8*)dst + dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To565RCCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt16* dst = (UInt16*)destination;

    while (stride > 0) {
        *dst = Pixel888To565((Address)src);

        src++;
        dst = (UInt16*)((UInt8*)dst - dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To666(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = Pixel888To666((Address)src);

        src++;
        dst++;
        stride--;
    }
}

Void ScanLineRECT888To666FLIP(Address destination, Address source, Int32 stride)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *--dst = Pixel888To666((Address)src);

        src++;
        stride--;
    }
}

Void ScanLineRECT888To666RCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = Pixel888To666((Address)src);

        src++;
        dst = (UInt32*)((UInt8*)dst + dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To666RCCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    Pixel* src = (Pixel *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = Pixel888To666((Address)src);

        src++;
        dst = (UInt32*)((UInt8*)dst - dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To888FLIP(Address destination, Address source, Int32 stride)
{
    UInt32* src = (UInt32 *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *--dst = *src;

        src++;
        stride--;
    }
}

Void ScanLineRECT888To888RCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    UInt32* src = (UInt32 *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = *src;

        src++;
        dst = (UInt32*)((UInt8*)dst + dstPitch);
        stride--;
    }
}

Void ScanLineRECT888To888RCCW(Address destination, Address source, Int32 stride, Int32 dstPitch)
{
    UInt32* src = (UInt32 *)source;
    UInt32* dst = (UInt32 *)destination;

    while (stride > 0) {
        *dst = *src;

        src++;
        dst = (UInt32*)((UInt8*)dst - dstPitch);
        stride--;
    }
}



void ScanLeftAAEdge(
            Point ps, Point pe,
            ScanLineList * scanlinelist,
            int startY, int height,
            const BitmapBufInfo * srcImg, const BitmapBufInfo * dstImg,
            int level)
{
	int dx=pe.x-ps.x;
	int dy=pe.y-ps.y;
	int xinc,yinc,i,x,y;
    Pixel *dst = NULL;
    Pixel *src = NULL;

	if (dx>0)
		xinc=1;
	else
		xinc=-1;

	if(dy>0)
		yinc=1;
	else
		yinc=-1;

	dx=abs(dx);
	dy=abs(dy);
	x=pe.x;
	y=pe.y;
	scanlinelist[y-startY].Left.x = x;
	scanlinelist[y-startY].Left.y = y;

    dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
    src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
    PixelRenderARGB32ToARGB32((Address)dst, (Address)src);


	x=ps.x;
	y=ps.y;
	scanlinelist[y-startY].Left.x = x;
	scanlinelist[y-startY].Left.y = y;

    dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
    src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
    PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

	i=0;

	if(dx==0&&dy==0) {
        dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
        src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
        PixelRenderARGB32ToARGB32((Address)dst, (Address)src);
	}
	else if(dx==0)
	{
		for(i=0;i<dy;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

            scanlinelist[y-startY].Left.x = x;
            scanlinelist[y-startY].Left.y = y;
			y+=yinc;
		}
	}
	else if(dy==0)
	{
		for(i=0;i<dx;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

			x+=xinc;
		}
	}
	else if(dx>dy)
	{
	    int alpha = 0;
	    if (xinc>0) {
    	    int y_16 = y<<16;
            int dy_16 = (dy<<16)/dx;

            for(i=0;i<dx;i++) {
                dst = (Pixel*)(dstImg->address + ((y_16>>16)+1) * dstImg->pitch) + x;
                src = (Pixel*)(srcImg->address + ((y_16>>16)+1) * srcImg->pitch) + x;
                alpha = (((y_16&0xFFFF)>>8)*level)>>8;
                if (alpha > 0) PixelRenderARGB32ToARGB32WithOpacity((Address)dst, (Address)src, alpha);

                scanlinelist[(y_16>>16)+1-startY].Left.x = x+1;
                scanlinelist[(y_16>>16)+1-startY].Left.y = (y_16>>16);
                y_16+=dy_16;
                x+=xinc;
            }
		}
		else {
    	    int y_16 = y<<16;
            int dy_16 = (dy<<16)/dx;
            for(i=0;i<dx;i++) {
                dst = (Pixel*)(dstImg->address + (y_16>>16) * dstImg->pitch) + x;
                src = (Pixel*)(srcImg->address + (y_16>>16) * srcImg->pitch) + x;
                alpha = (((0xFFFF-(y_16&0xFFFF))>>8)*level)>>8;
                if (alpha > 0) PixelRenderARGB32ToARGB32WithOpacity((Address)dst, (Address)src, alpha);

                scanlinelist[(y_16>>16)+1-startY].Left.x = x;
                scanlinelist[(y_16>>16)+1-startY].Left.y = (y_16>>16)+1;
                y_16+=dy_16;
                x+=xinc;
            }
		}
	}
	else
	{
	    int x_16 = x<<16;
        int dx_16 = (dx<<16)/dy;
        if (xinc<0) {
           dx_16=-dx_16;
        }
		for(i=0;i<dy;i++) {
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + (x_16>>16);
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + (x_16>>16);
            int alpha = (((0xFFFF-(x_16&0xFFFF))>>8)*level)>>8;
            if (alpha > 0) PixelRenderARGB32ToARGB32WithOpacity((Address)dst, (Address)src, alpha);

            scanlinelist[y-startY].Left.x = (x_16>>16)+1;
            scanlinelist[y-startY].Left.y = y;
		    x_16+=dx_16;
		    y+=yinc;
		}
	}
	return;
}

void ScanRightAAEdge(
            Point ps, Point pe,
            ScanLineList * scanlinelist,
            int startY, int height,
            const BitmapBufInfo * srcImg, const BitmapBufInfo * dstImg,
            int level)
{
	int dx=pe.x-ps.x;
	int dy=pe.y-ps.y;
	int xinc,yinc,i,x,y;
    Pixel *dst = NULL;
    Pixel *src = NULL;

	if (dx>0)
		xinc=1;
	else
		xinc=-1;

	if(dy>0)
		yinc=1;
	else
		yinc=-1;

	dx=abs(dx);
	dy=abs(dy);

	x=pe.x;
	y=pe.y;
	scanlinelist[y-startY].Right.x = x;
	scanlinelist[y-startY].Right.y = y;

	x=ps.x;
	y=ps.y;
	scanlinelist[y-startY].Right.x = x;
	scanlinelist[y-startY].Right.y = y;

	i=0;

	if(dx==0&&dy==0) {
        dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
        src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
        PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

	}
	else if(dx==0)
	{
		for(i=0;i<dy;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

            scanlinelist[y-startY].Right.x = x;
            scanlinelist[y-startY].Right.y = y;
			y+=yinc;
		}
	}

	else if(dy==0)
	{
		for(i=0;i<dx;i++)
		{
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + x;
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + x;
            PixelRenderARGB32ToARGB32((Address)dst, (Address)src);

			x+=xinc;
		}
	}

	else if(dx>dy)
	{
	    int alpha = 0;
	    if (xinc>0) {
    	    int y_16 = y<<16;
            int dy_16 = (dy<<16)/dx;
            for(i=0;i<dx;i++) {
                dst = (Pixel*)(dstImg->address + (y_16>>16) * dstImg->pitch) + x;
                src = (Pixel*)(srcImg->address + (y_16>>16) * srcImg->pitch) + x;
                alpha = (((0xFFFF-(y_16&0xFFFF))>>8)*level)>>8;
                if (alpha > 0) PixelRenderARGB32ToARGB32WithOpacity((Address)dst, (Address)src, alpha);

                scanlinelist[(y_16>>16)+1-startY].Right.x = x;
                scanlinelist[(y_16>>16)+1-startY].Right.y = (y_16>>16)+1;
                y_16+=dy_16;
                x+=xinc;
            }
		}
		else {
    	    int y_16 = y<<16;
            int dy_16 = (dy<<16)/dx;
            for(i=0;i<dx;i++) {
                dst = (Pixel*)(dstImg->address + ((y_16>>16)+1) * dstImg->pitch) + (x+1);
                src = (Pixel*)(srcImg->address + ((y_16>>16)+1) * srcImg->pitch) + (x+1);
                alpha = (((y_16&0xFFFF)>>8)*level)>>8;
                if (alpha > 0) PixelRenderARGB32ToARGB32WithOpacity((Address)dst, (Address)src, alpha);

                scanlinelist[(y_16>>16)+1-startY].Right.x = x;
                scanlinelist[(y_16>>16)+1-startY].Right.y = (y_16>>16);
                y_16+=dy_16;
                x+=xinc;
            }
		}
	}
	else
	{
	    int x_16 = x<<16;
        int dx_16 = (dx<<16)/dy;
        if (xinc<0) {
           dx_16=-dx_16;
        }
		for(i=0;i<dy;i++) {
            dst = (Pixel*)(dstImg->address + y * dstImg->pitch) + ((x_16>>16)+1);
            src = (Pixel*)(srcImg->address + y * srcImg->pitch) + ((x_16>>16)+1);
            int alpha = (((x_16&0xFFFF)>>8)*level)>>8;
            if (alpha > 0) PixelRenderARGB32ToARGB32WithOpacity((Address)dst, (Address)src, alpha);

            scanlinelist[y-startY].Right.x = (x_16>>16);
            scanlinelist[y-startY].Right.y = y;
		    x_16+=dx_16;
		    y+=yinc;
		}
	}
	return;
}


void FillPolygon(
                ScanLineList * scanlinelist,
                int startY, int height,
                const BitmapBufInfo * srcImg, const BitmapBufInfo * dstImg,
                int level)
{
    int y = 0;

    while (y<height) {
        int startX = scanlinelist[y].Left.x;
        int endX = scanlinelist[y].Right.x;
        int* dst = (int*)dstImg->address;
        ((unsigned char*&)dst)+=dstImg->pitch*(y+startY);
        dst+=startX;
        int* src = (int*)srcImg->address;
        ((unsigned char*&)src)+=srcImg->pitch*(y+startY);
        src+=startX;
        for (int x=startX;x<=endX;x++) {
            *dst = *src;
            src++;
            dst++;
        }
        y++;
    }
}
